package com.chuangke.system.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chuangke.admin.data.builder.DeptDataBuilder;
import com.chuangke.admin.data.builder.DictDataBuilder;
import com.chuangke.admin.data.builder.UserDataBuilder;
import com.chuangke.admin.service.SysDictService;
import com.chuangke.admin.util.DictUtils;
import com.chuangke.common.constant.Masks;
import com.chuangke.common.constant.SysConfigConstants;
import com.chuangke.common.constant.SysDictTypeConstants;
import com.chuangke.common.data.builder.DataBuildConfig;
import com.chuangke.common.data.builder.DataBuilder;
import com.chuangke.common.utils.BeanUtils;
import com.chuangke.common.utils.DateUtils;
import com.chuangke.framework.util.TreeUtils;
import com.chuangke.system.constant.SystemConstant;
import com.chuangke.system.dao.SysCertificateDao;
import com.chuangke.system.entity.SysCertificate;
import com.chuangke.system.entity.SysConfig;
import com.chuangke.system.service.SysCertificateService;
import com.chuangke.system.service.SysConfigService;

import cn.hutool.core.util.StrUtil;

@Service
public class SysCertificateServiceImpl implements SysCertificateService {

	@Autowired
	private SysCertificateDao sysCertificateDaoService;
	@Autowired
	private SysDictService sysDictService;
	@Autowired
	private SysConfigService sysConfigService;

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void saveOrUpdate(List<SysCertificate> models) {
		for (SysCertificate model : models) {
			DictUtils.autoHandleBeanAndSaveDict(sysDictService, Collections.singletonList(model), SysDictTypeConstants.SYS_STAFF,
					model.getDeptId(), "userId", "userName");

			if (Masks.BOOL_NO.equals(model.getIsDeadline())) {
				model.setExpireStatus(SystemConstant.CERTIFICATE_EXPIRE_STATUS_WGQ);
				continue;
			}

			String expireDateStr = model.getExpireDate();
			if (StrUtil.isBlank(expireDateStr)) {
				model.setExpireStatus(SystemConstant.CERTIFICATE_EXPIRE_STATUS_WGQ);
				continue;
			}

			Date expireDate = DateUtils.getDate(expireDateStr, "yyyyMMdd");

			SysConfig config = sysConfigService.find("SYSTEM", SysConfigConstants.CERTIFICATE_EXPIRE_DAYS);
			int expireDays = config == null ? 60 : Integer.parseInt(config.getParamValue());
			String expireStatus = null;
			if (expireDate.before(new Date())) {
				expireStatus = SystemConstant.CERTIFICATE_EXPIRE_STATUS_YGQ;
			} else {
				expireStatus = DateUtils.getDifDay(new Date(), expireDate) <= expireDays
						? SystemConstant.CERTIFICATE_EXPIRE_STATUS_JGQ
						: SystemConstant.CERTIFICATE_EXPIRE_STATUS_WGQ;
			}
			model.setExpireStatus(expireStatus);
		}

		sysCertificateDaoService.saveOrUpdateBatch(models);
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void delete(List<String> idList) {
		sysCertificateDaoService.removeBatchByIds(idList);
	}

	@Override
	public List<SysCertificate> findByDept(List<String> deptIds, Map<String, Object> params) {
		if (CollectionUtils.isEmpty(deptIds)) {
			return new ArrayList<>();
		}

		String expireStatus = (String) params.get("expireStatus");
		String isTrain = (String) params.get("isTrain");
		String userName = (String) params.get("userName");
		QueryWrapper<SysCertificate> qw = new QueryWrapper<>();
		qw.lambda().in(SysCertificate::getDeptId, deptIds);
		if (!StrUtil.isBlank(isTrain)) {
			qw.lambda().eq(SysCertificate::getIsTrain, isTrain);
		}
		if (!StrUtil.isBlank(expireStatus)) {
			qw.lambda().eq(SysCertificate::getExpireStatus, expireStatus);
		}
		List<SysCertificate> list = sysCertificateDaoService.list(qw);

		DataBuilder.of(list)
				.appendBuilder(new UserDataBuilder(), new DataBuildConfig("createdBy", "createdByName"),
						new DataBuildConfig("updatedBy", "updatedByName"), new DataBuildConfig("userId", "userName"))
				.appendBuilder(new DictDataBuilder(SysDictTypeConstants.SYS_CERTIFICATE_CATEGORY),
						new DataBuildConfig("categoryId", "categoryName"))
				.appendBuilder(new DictDataBuilder(SysDictTypeConstants.SYS_STAFF), new DataBuildConfig("userId", "userName"))
				.appendBuilder(new DeptDataBuilder(), new DataBuildConfig("deptId", "deptName")).build();

		if (!StrUtil.isBlank(userName)) {
			list = list.stream()
					.filter(item -> item.getUserName() != null && item.getUserName().contains(userName))
					.collect(Collectors.toList());
		}
		return list;
	}

	@Override
	public List<Map<String, Object>> findByDeptLevel(List<String> deptIds, Map<String, Object> params) {
		List<SysCertificate> list = this.findByDept(deptIds, params) ;
		List<Map<String, Object>> dataList = BeanUtils.beansToMaps(list) ;
		
		List<String> groupColumns = Arrays.asList("userId","userName") ;
		TreeUtils.buildParentDataByGroup(groupColumns, dataList) ;
		return dataList;
	}
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void handleExpired() {
		List<SysCertificate> models = sysCertificateDaoService.list();
		saveOrUpdate(models);
	}

}
